home *** CD-ROM | disk | FTP | other *** search
Wrap
Text File | 1986-01-13 | 8.0 KB | 242 lines | [ TEXT/ttxt]
StringHolder subclass: #ProtocolBrowser instanceVariableNames: 'list classDictionary selectedClass selectedSelector listIndex view isInstance originalClass listView ' classVariableNames: '' poolDictionaries: '' category: 'Interface-Protocol'! ProtocolBrowser comment: 'This class represents a browser in which you can examine the message interface of a particular class. ProtocolBrowser openForClass: className'! !ProtocolBrowser methodsFor: 'list access'! listIndex "Answer the current list index" ^listIndex! selectedClass "Answer the currently selected class from the menu" ^selectedClass! selectedSelector "Answer the currently selected selector from the menu" ^selectedSelector! selectorList "Answer the list of strings that show in the list menu" ^list! toggleListIndex: anInteger "Change selected item to anInteger. If already selected then deselect" | aString | anInteger = listIndex ifTrue: [listIndex_0. selectedSelector _ nil] ifFalse: [listIndex_anInteger. aString _ list at: anInteger. selectedSelector _ (aString copyUpTo: Character tab) asSymbol. selectedClass _ classDictionary at: selectedSelector]. self changed: #listIndex! ! !ProtocolBrowser methodsFor: 'text access'! contents "Answer the Symbol identifying the text of the menu" selectedSelector==nil ifTrue: [^'' asText] ifFalse: [^(selectedClass sourceCodeAt: selectedSelector) asText makeSelectorBoldIn: selectedClass]! contents: aText notifying: aController "Answer the message selector for changing the displayed text." | newSelector | newSelector _ selectedClass compile: aText classified: (selectedClass organization categoryOfElement: selectedSelector) notifying: aController. newSelector == nil ifTrue: [^false]. newSelector == selectedSelector ifFalse: [self newSelectorList: newSelector]. ^true! ! !ProtocolBrowser methodsFor: 'view changing'! displayMode: aSymbol "alter the display to be full or partial and class or instance oriented as directed by aSymbol" | exclusions | isInstance == aSymbol ifTrue: [^self]. view erase. aSymbol == #partialInstance | (aSymbol == #partialClass) ifTrue: [exclusions_Array new: 5; at: 1 put: Object; at: 2 put: Behavior; at: 3 put: ClassDescription; at: 4 put: Class; at: 5 put: (Object class)]. Cursor execute showWhile: [aSymbol == #fullInstance ifTrue: [self on: originalClass]. aSymbol == #fullClass ifTrue: [self on: (originalClass class)]. aSymbol == #partialInstance ifTrue: [self on: originalClass without: exclusions]. aSymbol == #partialClass ifTrue: [self on: (originalClass class) without: exclusions]]. listView list: self selectorList. self toggleListIndex: listIndex. view display. view emphasizeLabel. isInstance _ aSymbol ! ! !ProtocolBrowser methodsFor: 'private'! newSelectorList: aSelector "update the selector list with the newly compiled new selector" | oldClass newString oldString newIndex | newIndex _ 0. newString _ aSelector printString , ' (' , selectedClass name , ') '. oldClass _ classDictionary at: aSelector ifAbsent: [classDictionary add: (Association key: aSelector value: selectedClass). list do: [ :oldString | newIndex _ newIndex + 1. newString < oldString ifTrue: [list add: newString before: oldString. self readjustList: newIndex. ^self]]. list addLast: newString. self readjustList: newIndex + 1. ^self]. oldClass == selectedClass ifFalse: "looks like they recompiled to a different class" [classDictionary at: aSelector put: selectedClass. list do: [ :oldString | newIndex _ newIndex + 1. aSelector == (oldString copyUpTo: Character tab) asSymbol ifTrue: [list at: newIndex put: newString. self readjustList: newIndex. ^self] ] ]! on: aClass "Create the protocol browser for the class, aClass." | defClass label| list _ OrderedCollection new. classDictionary _ Dictionary new. aClass allSelectors asSortedCollection do: [:selector | defClass _ aClass whichClassIncludesSelector: selector. list add: selector printString , ' (' , defClass name , ') '. classDictionary add: (Association key: selector value: defClass)]. label _ 'Entire protocol of: ' , aClass name. view label: label ! on: aClass without: aCollection "Create the protocol browser for the class, aClass, leaving out any classes in aCollection." | defClass label| list _ OrderedCollection new. classDictionary _ Dictionary new. aClass allSelectors asSortedCollection do: [:selector | defClass _ aClass whichClassIncludesSelector: selector. (defClass == aClass or: [(aCollection includes: defClass) not]) ifTrue: [list add: selector printString , ' (' , defClass name , ') '. classDictionary add: (Association key: selector value: defClass)]]. label _ 'Partial protocol of: ' , aClass name. view label: label ! originalClass: aClass view: aView listView: anotherView "remember where we started" isInstance _ #partialInstance. originalClass_aClass. listView _ anotherView. view_aView! readjustList: newIndex "after compiling a method with a new selector, get the list back in shape on the menu" listIndex _ 0. self toggleListIndex: newIndex. listView list: list. listView moveSelectionBox: newIndex. self inspect. ^self ! ! "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "! ProtocolBrowser class instanceVariableNames: ''! !ProtocolBrowser class methodsFor: 'instance creation'! openForClass: aClass "Create and schedule a browser for the entire protocol of the class. " | topView aPBrowser myList myCode | aPBrowser _ super new. topView _ StandardSystemView new. myList _ ListView new. aPBrowser originalClass: aClass view: topView listView: myList. Cursor execute showWhile: [aClass == Object ifTrue: [aPBrowser on: aClass] ifFalse: [aPBrowser on: aClass without: (Array with: Object)]]. topView model: aPBrowser. topView minimumSize: 200 @ 200. myList model: aPBrowser controller: ProtocolListController new. myList borderWidthLeft: 2 right: 2 top: 2 bottom: 2. myList list: aPBrowser selectorList. myCode _ StringHolderView new. myCode model: aPBrowser controller: BrowserCodeController new. myCode borderWidthLeft: 2 right: 2 top: 0 bottom: 2. topView addSubView: myList. topView addSubView: myCode. myList window: myList window viewport: (myCode viewport topLeft corner: myCode viewport topRight + (0@100)). myCode window: myCode window viewport: (myCode viewport topLeft +(0@100) corner: myCode viewport bottomRight). myList controller yellowButtonMenu: (PopUpMenu labels: 'senders implementors messages partial instance partial class full instance full class' lines: #( 3 5)) yellowButtonMessages: #(browseSenders browseImplementors browseMessages partialInstance partialClass fullInstance fullClass ). topView controller open! ! ListController subclass: #ProtocolListController instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Interface-Protocol'! !ProtocolListController methodsFor: 'list functions'! browseImplementors "Create a message-set browser for the implementors of the selected message. " Smalltalk browseAllImplementorsOf: self model selectedSelector! browseMessages "Create a menu of the messages in the selected method and then, if the user selects a menu item, create a message-set browser for the methods that implement it. " Smalltalk showMenuThenBrowse: (self model selectedClass compiledMethodAt: self model selectedSelector) messages asSortedCollection! browseSenders "Create a message-set browser for the methods that include the selected message. " Smalltalk browseAllCallsOn: self model selectedSelector! ! !ProtocolListController methodsFor: 'class changing'! fullClass "change the view to the class variety" self model displayMode: #fullClass! fullInstance "change the view to the instance variety" self model displayMode: #fullInstance! partialClass "change the view to the class variety" self model displayMode: #partialClass! partialInstance "change the view to the instance variety" self model displayMode: #partialInstance! !